/*
Kakine
ActionScript Framework
Copyright © 2011, PUNY, LLC.

This file is part of KAKINE.

KAKINE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KAKINE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with KAKINE.  If not, see <http://www.gnu.org/licenses/>.
*/ 
package com.puny.mvc.controllers.platformer
{
	import com.puny.mvc.controllers.Controller;
	
	import flash.events.Event;

	/**
	 * $Revision: 706 $
	 * Can move itself by Verlet method.
	 */
	public class VerletController extends Controller
	{
		public static const MOVING:String = "moving";
		private var _x:Number=0;
		private var _y:Number=0;
		private var _dt2:Number;
		private var _movingEvent:Event = new Event(MOVING);
		public function VerletController(filename:String=null)
		{
			super(filename);
		}
		/**
		 * Set initial position and velocity.
		 */
		public function initialize(ix:Number=0,iy:Number=0,vx:Number=0,vy:Number=0):void {
			_x = ix - vx;
			_y = iy - vy;
			super.x = ix;
			super.y = iy;
		}
		/**
		 * Calculate an interval between frames.
		 */
		override public function beforeReady():void {
			super.beforeReady();
			var dt:Number = 1/24;
			_dt2 = dt * dt;
		}
		
		/**
		 * verlet formular
		 * @param r0 
		 */
		protected function verlet(r0:Number,r1:Number,g:Number):Number {
			return 2 * r1 - r0 + g * _dt2;
		}
		
		/**
		 * x position setter
		 */
		override public function set x(value:Number):void {
			_x = int(super.x * 100) / 100;
			if (-.25 < value - super.x && value - super.x < .25) {
				return;
			}
			super.x = int(value * 100) /100;
			if (_x != value) {
				dispatchEvent(_movingEvent.clone());
			}
		}
		
		override public function set y(value:Number):void {
			_y = int(super.y * 100) / 100;
			if (-.25 < value - super.y && value - super.y < .25) {
				return;
			}
			super.y = int(value * 100) / 100;
			if (_y != value) {
				dispatchEvent(_movingEvent.clone());
			}
		}

		public function traceX():Number {
			return _x;
		}
		
		public function traceY():Number {
			return _y;
		}

		public function boundYAt(here:Number):void {
			here = here << 1;
			var tmp:Number = y;
			y = here - traceY();
			y = here - tmp;
		}
		
		public function boundXAt(here:Number):void {
			here = here << 1;
			var tmp:Number = x;
			x = here - traceX();
			x = here - tmp;
		}
		
		public function stopXAt(here:Number):void {
			x = here;
			x = here;
		}
		
		public function stopYAt(here:Number):void {
			y = here;
			y = here;	
		}
		
	}
}